/*	Copyright 2007 - Xavier Baro (xbaro@cvc.uab.cat)

	This file is part of eapmlib.

    Eapmlib is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or any 
	later version.

    Eapmlib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CABWEAKLEARNER_H
#define __CABWEAKLEARNER_H

#include "EvolutiveLib.h"
#include "AdaBoost.h"
#include "ThrClassifier.h"
#include "IntSamplesSet.h"
#include "SamplesEvaluator.h"
#include "DissociatedDipole.h"
#include "EAPMLearner.h"
#include "ProbModel.h"
 
namespace Evolutive {

	//! Defines the dipoles type
	enum EVOLUTIVELIB_API WL_DIPOLE_TYPE {WLD_DIPOLES,WLD_HAAR,WLD_WDIPOLES};

	//! Class that defines a weak learner that uses an EAPM to find dipole-like feature
	class EVOLUTIVELIB_API CWLEAPMDipole : public CABWeakLearner
		{
			//! Methods
		public:
			//! Default constructor		
			CWLEAPMDipole(void);

			//! Default destructor
			virtual ~CWLEAPMDipole(void);		

#ifdef USE_OPENCV
			//! Find the weak classifier (form base class)
			virtual CClassifier* GetWeakClassifier(double *Weights,bool *Mask,int *ClassOutput);

			//! Returns the number of samples in the training set (from base class)
			virtual int GetNumSamples(void);

			//! Returns a pointer to the labels (from base class)
			virtual int* GetLabelsPtr(void);

			//! Sets the samples set
			void SetSamplesSet(CIntSamplesSet *SamplesSet);

			//! Set probabilistic model for the EAPM
			void SetProbModel(CProbModel *Model);
			
			//! Apply the classifier to the samples set (from base class)
			virtual void Classify(CClassifier *Classifier,int *Class);
			virtual void Classify(CClassifier *Classifier,double *Class);
			
			//! Set the number of iterations for the evolutive algorithm
			void SetNumIterations(int NumIters);

			//! Change the well classified negative samples (from base class)
			virtual void UpdateSamplesSet(CClassifier *Classifier);
												
		protected:

			//! Convert the original labels in the training set into a binary representation with values {+1,-1}
			void StoreLabels(CIntSamplesSet *SamplesSet);

			//! Assign the parameters related to the samples set
			void ApplySamplesParameters(void);

#endif //USE_OPENCV

			//! Attributes
		protected:				
			//! Pointer to the training set
			CIntSamplesSet *m_SamplesSet;

#ifdef USE_OPENCV
			//! Samples Evaluator object
			CSamplesEvaluator m_SmpEvaluator;

			//! Dipole object used to define the classification object
			CDissociatedDipole m_Dipole;

			//! Classifier object used to evaluate the samples
			CThrClassifier m_Classifier;
#endif
			//! Number of samples in the training set
			int m_NumSamples;

			//! Translated list of the samples labels
			int *m_SamplesLabel;

			//! EAPM Learner object
			CEAPMLearner m_Learner;

			//! Type of dipoles to be used
			WL_DIPOLE_TYPE m_FeatureType;

			//! Maximum number of iterations of the evolutive algorithm
			int m_NumIters;

			//! Number of individuals in the populations
			int m_PopSize;

			//! Number of elitist individuals selected at each iteration
			int m_NumElitism;

			//! Model tolerance. Used to stop the evolutive algorithm
			double m_ModelTolerance;

			//! Percentage of the population used to estimate the new model
			double m_ModelEstimationPer;

			//! Max number of iterations without improvement before to stop the EAPM
			int m_MaxStaticIterations;

			//! Number of variables to learn
			int m_NumVariables;

			//! Bits to describe each variable (this is also used in decimal representation to obtain the ranges)
			int *m_VarNumBits;

			//! Defines the default action when a zero value is archieved
			THRCLASS_EQTHR m_DefZeroValue;
		};	
} //__CABWEAKLEARNER_H

#endif
